#include "BaseType.h"
#include "Tracer.h"

/**
 * 组合模式(部分整体模式)：
 * 1.将对象组合成树形结构进行表示
 * 2.部分与整体具有相似的行为
 * 适用场景：
 * 1.菜单/子菜单场景
 * 2.整体/部分
 **/

//部分和整体的抽象接口
class FileNode{
DECL_CLASSNAME(FileNode)
public:
    virtual void addNode(std::shared_ptr<FileNode> node)=0;
    virtual int wordCount()=0;
};

//部分
class File:public FileNode{
DECL_CLASSNAME(File)
public:
    void addNode(std::shared_ptr<FileNode> node) override
    {
        using namespace libemb;
        TRACE_ERR_CLASS("cannot add node!");
    }
    int wordCount() override
    {
        return 1;
    }
};

//整体：可以包含整体及部分的子对象
class Directory:public FileNode{
DECL_CLASSNAME(Directory)
public:
    void addNode(std::shared_ptr<FileNode> node) override
    {
        m_fileNodes.push_back(node);
    }

    int wordCount() override
    {
        int count=0;//文件夹不计算字数
        for(auto file: m_fileNodes)
        {
            count += file->wordCount();
        }
        return count;
    }

private:
    std::vector<std::shared_ptr<FileNode>> m_fileNodes;
};

using namespace libemb;
int main()
{
    Tracer::getInstance().setLevel(TRACE_LEVEL_DBG);
	Tracer::getInstance().addSink(std::make_shared<STDSink>()).start();

    auto dir1 = std::make_shared<::Directory>();
    auto dir2 = std::make_shared<::Directory>();
    auto file1 = std::make_shared<::File>();
    auto file2 = std::make_shared<::File>();
    auto file3 = std::make_shared<::File>();
    dir1->addNode(file1);
    dir2->addNode(file2);
    dir2->addNode(file3);
    dir1->addNode(dir2);

    TRACE_INFO("dir1 word count:%d",dir1->wordCount());
    TRACE_INFO("dir2 word count:%d",dir2->wordCount());
    return RC_OK;
}